package top.huxy.web.core;


import top.huxy.web.exception.ParamIllegalException;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Collection;

/**
 * @author aproz
 * @Date 2022/5/11
 */
public interface Verifiable extends Serializable {

    /**
     * 进行属性校验
     */
    void validate();

    /**
     * 反射根据获取到name的值，调用ifNullThrow(String,Object)
     *
     * @param name 属性名称
     */
    default void ifNullThrow(String name) {
        Object o;
        try {
            Field field = this.getClass().getDeclaredField(name);
            field.setAccessible(true);
            o = field.get(this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        ifNullThrow(name, o);
    }

    /**
     * 如果o是null，则抛异常
     *
     * @param name 可能为空的属性名
     * @param o    属性的值
     */
    default void ifNullThrow(String name, Object o) {
        if (o == null) {
            throw new ParamIllegalException(String.format("%s是必需的", name));
        }
    }

    /**
     * 如果o是null，则抛异常
     *
     * @param name      可能为空的属性名
     * @param o         属性的值
     * @param strFormat 异常格式化内容
     */
    default void ifNullThrow(String name, Object o, String strFormat) {
        if (o == null) {
            throw new ParamIllegalException(String.format(strFormat, name));
        }
    }

    /**
     * 反射根据获取到name的值，调用ifEmptyThrow(String,Object)
     *
     * @param name 属性名称
     */
    default void ifEmptyThrow(String name) {
        Object o;
        try {
            Field field = this.getClass().getDeclaredField(name);
            field.setAccessible(true);
            o = field.get(this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        ifEmptyThrow(name, o);
    }

    /**
     * 详见 ifEmptyThrow(String,Object,String)
     *
     * @param name 属性名称
     * @param o    属性值
     */
    default void ifEmptyThrow(String name, Object o) {
        ifEmptyThrow(name, o, "%s不能为空");
    }

    /**
     * o is null，则抛异常
     * o is CharSequence，调用trim后长度为0则抛异常
     * o is Collection，集合是空的则抛异常
     * o is []，数组是空的则抛异常
     *
     * @param name      属性名称
     * @param o         属性值
     * @param strFormat 异常信息格式化，第一个参数是name
     */
    default void ifEmptyThrow(String name, Object o, String strFormat) {
        if (o == null) {
            throw new ParamIllegalException(String.format(strFormat, name));
        }
        if (o instanceof CharSequence) {
            if (o.toString().trim().length() == 0) {
                throw new ParamIllegalException(String.format(strFormat, name));
            }
        } else if (o instanceof Collection) {
            if (((Collection<?>) o).isEmpty()) {
                throw new ParamIllegalException(String.format(strFormat, name));
            }
        } else if (o.getClass().isArray()) {
            if (((Object[]) o).length == 0) {
                throw new ParamIllegalException(String.format(strFormat, name));
            }
        }
    }
}
